using System;
using System.Collections.Generic;
using SlimDX.DirectInput;
using SlimMath;

namespace JamesZhao.Engine
{
    public class InputManager : Manager
    {
        private readonly DirectInput _directInput;
        private readonly Dictionary<Key, bool> _keyState;
        private readonly Keyboard _keyboard;
        private readonly List<Key> _keysToListenFor;
        private readonly Mouse _mouse;
        private KeyboardState _cachedKeyboardState;
        private MouseState _cachedMouseState;

        public InputManager(GameEngine gameEngine)
            : base(gameEngine)
        {
            _keyState = new Dictionary<Key, bool>();
            _directInput = new DirectInput();
            _keyboard = new Keyboard(_directInput);
            _mouse = new Mouse(_directInput);
            _keysToListenFor = new List<Key>();

            _cachedMouseState = new MouseState();
            _cachedKeyboardState = new KeyboardState();

            AddButtonInput(Key.W);
            AddButtonInput(Key.A);
            AddButtonInput(Key.S);
            AddButtonInput(Key.D);
        }

        public Vector2 MouseDelta { get; private set; }

        public void AddButtonInput(Key key)
        {
            _keysToListenFor.Add(key);
        }

        private void UpdateMouseDelta()
        {
            //profiler hotspot
            _mouse.GetCurrentState(ref _cachedMouseState);
            MouseDelta = new Vector2(_cachedMouseState.X, _cachedMouseState.Y);
        }

        public float GetAxis(string axis)
        {
            throw new NotImplementedException();
        }

        public bool GetKey(Key key)
        {
            return _keyState[key];
        }

        public override void Initialize()
        {
            //_keyboard.SetCooperativeLevel(GameEngine.GraphicsManager.RenderWindow.Form, CooperativeLevel.Nonexclusive);
            _keyboard.Acquire();

            //_mouse.SetCooperativeLevel(GameEngine.GraphicsManager.RenderWindow.Form, CooperativeLevel.Nonexclusive);
            _mouse.Acquire();
        }

        public override void Update()
        {
            //hotspot
            _keyboard.GetCurrentState(ref _cachedKeyboardState);
            foreach (Key k in _keysToListenFor)
            {
                _keyState[k] = _cachedKeyboardState.IsPressed(k);
            }
            UpdateMouseDelta();
        }
    }
}